/**
 * 对 axios 进行二次封装，封装网络请求文件
 */

// 导入 axios
import axios, { type Method } from 'axios'
// import {} from 'vant'
import router from '@/router'
import { getToken } from './token-utils'

// 创建实例1
const sphInstance = axios.create({
  baseURL: '/sph-dev',
  // baseURL: 'http://sph-h5-api.atguigu.cn',
  timeout: 10000
})
// 创建实例2
const wyInstance = axios.create({
  // baseURL: import.meta.env.VITE_API_URL,
  baseURL: '/wy-dev',
  // baseURL: 'http://sph-h5-api.atguigu.cn',
  timeout: 10000
})

// 添加请求拦截器
sphInstance.interceptors.request.use(
  (config:any) => {
    // 在发送请求之前做些什么

    // 需要先从本地获取 token
    const token = getToken()
    // 判断是否存在，存在以后再添加到请求头中
    // 如果存在 token，并且 headers 也存在，在添加 token
    // 其实 headers 本身是存在的，但是类型定义为可选的了
    // 为了防止类型报错，所以写了一个 &&
    if (token && config.headers) {
      config.headers.token = token
    }

    return config
  },
  (error:any) => {
    // 对请求错误做些什么
    return Promise.reject(error)
  }
)


wyInstance.interceptors.request.use(
  (config:any) => {
    // 在发送请求之前做些什么

    // 需要先从本地获取 token
    const token = getToken()
    // 判断是否存在，存在以后再添加到请求头中
    // 如果存在 token，并且 headers 也存在，在添加 token
    // 其实 headers 本身是存在的，但是类型定义为可选的了
    // 为了防止类型报错，所以写了一个 &&
    if (token && config.headers) {
      config.headers.token = token
    }

    return config
  },
  (error:any) => {
    // 对请求错误做些什么
    return Promise.reject(error)
  }
)

// 添加响应拦截器
sphInstance.interceptors.response.use(
  (response:any) => {
    // response 是 axios 包裹以后返回的数据
    const res = response.data

    // 判断请求状态码是否等于 200 或者 20000
    if (res.code !== 200 && res.code !== 20000) {
      // 请求错误的
      // 需要判断是否是 token 过期
      if (res.code !== 20001) {
        // 其他错误
        // ElMessage({
        //   message: '请求异常，请稍后重试',
        //   type: 'error'
        // })
      } else {
        // token 过期
        // ElMessage({
        //   message: '身份认证失败，请重新登录',
        //   type: 'error'
        // })

        // 在 Store 中存在退出的 actions 方法
        // 在 actions 方法中清除了用户信息、也清除了token
        // 所以直接调用 actions 方法即可

        // 如果是在非 vue 组件中使用 Store，实例化不能够在 .js 顶部实例化
        // 需要再使用的位置进行实例化才可以，否则会报错
        // const userInfoStore = useUserInfoStore()

        // 调用退出的方法
        // userInfoStore.reset()

        // 需要跳转到登录页面
        // 在非 vue 文件中，可以导入 router 实例，然后调用实例方法
        router.replace('/login')
      }

      // 以后再组件中需要通过 instance.get('xxx')
      // 不管请求是 token 问题还是其他错误，都需要将错误往下传递
      return Promise.reject(res || 'error' || new Error('error'))
    } else {
      // 请求成功，直接将服务器真正响应的数据返回即可
      return res
    }
  },
  (error) => {
    // 什么时候会进入错误的回调函数
    // 1. 路径出现错误，也就是 404
    // 2. 网络异常的时候，也会走响应拦截器的回调函数

    // ElMessage({
    //   message: '网络异常，请检查网络',
    //   type: 'error'
    // })

    if (error.message.indexOf('timeout') != -1) {
      // ElMessage.error('网络超时')
    } else if (error.message == 'Network Error') {
      // ElMessage.error('网络连接错误')
    } else {
      // if (error.response.data) ElMessage.error(error.response.statusText)
      // else ElMessage.error('接口路径找不到')
    }

    return Promise.reject(error)
  }
)

wyInstance.interceptors.response.use(
  (response:any) => {
    // response 是 axios 包裹以后返回的数据
    const res = response.data

    // 判断请求状态码是否等于 200 或者 20000
    if (res.code !== 200 && res.code !== 20000) {
      // 请求错误的
      // 需要判断是否是 token 过期
      if (res.code !== 20001) {
        // 其他错误
        // ElMessage({
        //   message: '请求异常，请稍后重试',
        //   type: 'error'
        // })
      } else {
        // token 过期
        // ElMessage({
        //   message: '身份认证失败，请重新登录',
        //   type: 'error'
        // })

        // 在 Store 中存在退出的 actions 方法
        // 在 actions 方法中清除了用户信息、也清除了token
        // 所以直接调用 actions 方法即可

        // 如果是在非 vue 组件中使用 Store，实例化不能够在 .js 顶部实例化
        // 需要再使用的位置进行实例化才可以，否则会报错
        // const userInfoStore = useUserInfoStore()

        // 调用退出的方法
        // userInfoStore.reset()

        // 需要跳转到登录页面
        // 在非 vue 文件中，可以导入 router 实例，然后调用实例方法
        router.replace('/login')
      }

      // 以后再组件中需要通过 instance.get('xxx')
      // 不管请求是 token 问题还是其他错误，都需要将错误往下传递
      return Promise.reject(res || 'error' || new Error('error'))
    } else {
      // 请求成功，直接将服务器真正响应的数据返回即可
      return res
    }
  },
  (error:any) => {
    // 什么时候会进入错误的回调函数
    // 1. 路径出现错误，也就是 404
    // 2. 网络异常的时候，也会走响应拦截器的回调函数

    // ElMessage({
    //   message: '网络异常，请检查网络',
    //   type: 'error'
    // })

    if (error.message.indexOf('timeout') != -1) {
      // ElMessage.error('网络超时')
    } else if (error.message == 'Network Error') {
      // ElMessage.error('网络连接错误')
    } else {
      // if (error.response.data) ElMessage.error(error.response.statusText)
      // else ElMessage.error('接口路径找不到')
    }

    return Promise.reject(error)
  }
)


// 将实例暴露出去
export { sphInstance, wyInstance }
